package config

import (
	"os"
	"strconv"

	"github.com/joho/godotenv"
)

// BaseConfig is the base configuration for the application.
type BaseConfig struct {
	Port        uint64
	LogLevel    string
	Environment string
	Database    DatabaseConfig
}

// DatabaseConfig is the configuration for the database.
type DatabaseConfig struct {
	Host     string
	Port     uint64
	User     string
	Password string
	Database string
}

// constant
const (
	PortEnvVar             = "PORT"
	LogLevelEnvVar         = "LOG_LEVEL"
	EnvironmentEnvVar      = "ENVIRONMENT"
	DatabaseHostEnvVar     = "DATABASE_HOST"
	DatabasePortEnvVar     = "DATABASE_PORT"
	DatabaseUserEnvVar     = "DATABASE_USER"
	DatabasePasswordEnvVar = "DATABASE_PASSWORD"
	DatabaseNameEnvVar     = "DATABASE_NAME"
)

// LoadConfig loads the configuration from the environment variables.
func LoadConfig() (*BaseConfig, error) {
	// Load .env file if it exists
	_ = godotenv.Load()

	config := &BaseConfig{
		Port:        9980,
		LogLevel:    "info",
		Environment: "development",
		Database: DatabaseConfig{
			Host:     "localhost",
			Port:     3306,
			User:     "root",
			Password: "password",
			Database: "agent_design",
		},
	}

	if portStr, ok := os.LookupEnv(PortEnvVar); ok {
		if port, err := strconv.ParseUint(portStr, 10, 64); err == nil {
			config.Port = port
		}
	}

	if logLevelStr, ok := os.LookupEnv(LogLevelEnvVar); ok {
		config.LogLevel = logLevelStr
	}

	if environmentStr, ok := os.LookupEnv(EnvironmentEnvVar); ok {
		config.Environment = environmentStr
	}

	if databaseHostStr, ok := os.LookupEnv(DatabaseHostEnvVar); ok {
		config.Database.Host = databaseHostStr
	}

	if databasePortStr, ok := os.LookupEnv(DatabasePortEnvVar); ok {
		if port, err := strconv.ParseUint(databasePortStr, 10, 64); err == nil {
			config.Database.Port = port
		}
	}

	if databaseUserStr, ok := os.LookupEnv(DatabaseUserEnvVar); ok {
		config.Database.User = databaseUserStr
	}

	if databasePasswordStr, ok := os.LookupEnv(DatabasePasswordEnvVar); ok {
		config.Database.Password = databasePasswordStr
	}

	if databaseNameStr, ok := os.LookupEnv(DatabaseNameEnvVar); ok {
		config.Database.Database = databaseNameStr
	}

	return config, nil
}
